package gee

import (
	"fmt"
	"log"
	"net/http"
	"runtime"
	"strings"
)

func Recovery() HandlerFunc {
	return func(ctx *Context) {
		defer func() {
			if err := recover(); err != nil {
				log.Printf("%s\n\n", trace(fmt.Sprint(err)))
				ctx.Fail(http.StatusInternalServerError, "Internal Server Error")
			}
		}()
		ctx.Next()
	}
}

func trace(message string) string {
	pcs := make([]uintptr, 50)
	n := runtime.Callers(3, pcs[:])

	str := &strings.Builder{}
	str.WriteString(message + "\nTraceback:")
	for i := 0; i < n; i++ {
		_, file, line, _ := runtime.Caller(i)
		str.WriteString(fmt.Sprintf("\n\t%s:%d", file, line))
	}
	return str.String()
}
